package com.shelpe.services.scheduler.item.campaign;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;

import com.shelpe.services.scheduler.item.adgroup.AdgroupReader;
import com.shelpe.services.scheduler.po.Auth;
import com.shelpe.services.scheduler.po.Campaigns;
import com.shelpe.services.scheduler.po.Users;
import com.shelpe.services.scheduler.repository.AuthRepository;
import com.shelpe.services.scheduler.repository.CampaignsRepository;
import com.shelpe.services.scheduler.repository.UsersRepository;
import com.shelpe.services.scheduler.util.Util;

@Component("campaignReaderTest")
@Scope("step")	
public class CampaignReader implements ItemReader<Campaigns>{

	private static final Logger logger = LoggerFactory.getLogger(AdgroupReader.class);
	
	@Autowired
	private UsersRepository userRep;
	
	@Autowired
	private CampaignsRepository camRep;
	
	@Autowired
	private AuthRepository authRep;
    
    private final Long pageNo;
    
    private final Long pageSize;
    
    private final Long subIndex;
    
    private final Long subPages;
    
    private final Long userId;
    
    private final List<Long> mainInnerUserId = new ArrayList<Long>();
    
    private int currentUser;
    
    private int campaignNum;
    
    private List<Users> onePage;
    
    private List<Campaigns> campaigns;
   
    
    @Autowired
    public CampaignReader(@Value("#{jobParameters['pageNo']}")final Long pageNo, @Value("#{jobParameters['pageSize']}")final Long pageSize,
    		@Value("#{jobParameters['subIndex']}")final Long subIndex, @Value("#{jobParameters['subPages']}")final Long subPages,
    		@Value("#{jobParameters['userId']}")final Long userId, @Value("#{jobParameters['mainInnerUserId']}")final String mainInnerUserId){
        
        this.pageNo = pageNo;
        this.pageSize = pageSize;
        this.subIndex = subIndex;
        this.subPages = subPages;
        this.currentUser = 0;
        this.campaignNum = 0;
        this.userId = userId;
        if(mainInnerUserId != null){ 
            String[] innerUserId = mainInnerUserId.split(",");
            if(innerUserId != null && innerUserId.length > 0){
            	for(int i = 0; i < innerUserId.length; i++){
            		this.mainInnerUserId.add(Long.valueOf(innerUserId[i]));
            	}
            }
        }
    }
    
	@Override
	public Campaigns read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
		// TODO Auto-generated method stub
		if(onePage == null || onePage.size() == 0){
			
			if(userId != null){
				Users user = userRep.findOne(userId);
				onePage = new ArrayList<Users>();
				onePage.add(user);
			}else{
				
				if(pageNo >= 0 && pageSize > 0){
					
					Sort sort = new Sort("nick");
					Pageable pager = new PageRequest(pageNo.intValue(), pageSize.intValue(), sort);
					Page<Users> list = userRep.findAll(pager);
					
					List<Users> tempList = list.getContent();
					
					List<Users> temp = Util.getSubTaskList(tempList, subIndex, subPages);	
					
					filterAndSortUsers(temp);
				}
	
			}
		}
		
		while( (onePage != null && currentUser < onePage.size()) 
				&& (!(campaigns != null && campaignNum < campaigns.size())) ){

			Users user = onePage.get(currentUser);	
			currentUser++;
			campaigns = camRep.findByUserId(user.getUserId());
			campaignNum = 0;
		}
		
		if(campaigns != null && campaignNum < campaigns.size()){
			Campaigns campaign = campaigns.get(campaignNum);
			campaignNum++;
			
			return campaign;
		}

		return null;
	}
	
	private void filterAndSortUsers(List<Users> list){
		
		if(list != null && list.size() > 0){
			List<Users> temp = new ArrayList<Users>();
			for(Users user : list){
				Long userId = user.getUserId();
				Long authorizedTo = user.getAuthorizedTo();
				
				if(userId > 0 || mainInnerUserId.contains(authorizedTo)){
					temp.add(user);
				}else{
					List<Auth> authList = authRep.findByUserId(userId);
					if(authList != null && authList.size() > 0){
						temp.add(user);
					}
				}
			}
			
			onePage = new ArrayList<Users>();
			onePage.addAll(temp);	
			Collections.sort(onePage, new Comparator<Users>(){

				@Override
				public int compare(Users o1, Users o2) {
					// TODO Auto-generated method stub
					long userId1 = o1.getUserId();
					long userId2 = o2.getUserId();
					return userId1 == userId2 ? 0 : (userId1 < userId2 ? 1 : -1);
				}		
			});
		}
	}

}
